package com.hontech.bread.ui.parts

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.FrameLayout
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexDirection
import com.google.android.flexbox.FlexWrap
import com.google.android.flexbox.FlexboxLayoutManager
import com.hontech.bread.R
import com.hontech.bread.api.CTYPE_APK
import com.hontech.bread.api.CTYPE_BIN
import com.hontech.bread.api.Firm
import com.hontech.bread.api.downloadApk
import com.hontech.bread.api.downloadBin
import com.hontech.bread.api.firmQuery
import com.hontech.bread.device.DeviceStatus
import com.hontech.bread.device.ota
import com.hontech.bread.ui.dialog.runProg
import com.hontech.bread.ui.view.LabelTextView
import com.hontech.bread.utils.AppTask
import com.hontech.bread.utils.EmptyEdge
import com.hontech.bread.utils.Version
import com.hontech.bread.utils.installApk2
import com.hontech.bread.utils.onClick
import com.hontech.bread.utils.registerEvent
import com.hontech.bread.utils.stringById
import com.hontech.bread.utils.unregister
import kotlinx.coroutines.delay
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class OtaParts(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) {

    private val rv: RecyclerView

    private val ltApk: LabelTextView
    private val ltBin: LabelTextView

    init {
        val view = LayoutInflater.from(context).inflate(R.layout.parts_ota, this)

        view.findViewById<Button>(R.id.id_ota_btn_apk).onClick { onClickGetApk() }
        view.findViewById<Button>(R.id.id_ota_btn_bin).onClick { onClickGetBin() }
        ltApk = view.findViewById(R.id.id_ota_apk_version)
        ltBin = view.findViewById(R.id.id_ota_bin_version)

        rv = view.findViewById(R.id.id_ota_rv)
        rv.edgeEffectFactory = EmptyEdge()
        rv.layoutManager = FlexboxLayoutManager(context, FlexDirection.ROW, FlexWrap.WRAP)

        AppTask.post {
            ltApk.set(Version)
        }
    }

    private suspend fun onClickGetApk() {

        runProg(stringById(R.string.text_query), stringById(R.string.text_query_apk)) {
            val firms = firmQuery(CTYPE_APK)
            rv.adapter = Adapter(CTYPE_APK, firms)
        }
    }

    private suspend fun onClickGetBin() {
        runProg(stringById(R.string.text_query), stringById(R.string.text_query_bin)) {
            val firms = firmQuery(CTYPE_BIN)
            rv.adapter = Adapter(CTYPE_BIN, firms)
        }
    }

    override fun onWindowVisibilityChanged(visibility: Int) {
        super.onWindowVisibilityChanged(visibility)
        if (visibility == VISIBLE) {
            registerEvent(this)
        } else {
            unregister(this)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    fun update(status: DeviceStatus) {
        ltBin.set(status.version)
    }

}

private class Item(view: View) : RecyclerView.ViewHolder(view) {

    private val tvVersion = view.findViewById<LabelTextView>(R.id.id_item_ota_version)
    private val tvDescription = view.findViewById<LabelTextView>(R.id.id_item_ota_description)
    private val tvSize = view.findViewById<LabelTextView>(R.id.id_item_ota_size)
    private val tvDate = view.findViewById<LabelTextView>(R.id.id_item_ota_date)
    private val btnUpdate = view.findViewById<Button>(R.id.id_item_ota_update)

    private suspend fun onUpdateApk(id: Long) {
        runProg(stringById(R.string.text_update2), stringById(R.string.text_update_apk)) { dialog ->
            val path = downloadApk(id, "client.apk") {
                dialog.setMsg("${stringById(R.string.text_down_prog)}:$it%")
            }

            delay(50)
            dialog.setMsg(stringById(R.string.text_install))
            delay(50)
            installApk2(path)
        }
    }

    private suspend fun onUpdateBin(id: Long) {
        runProg(stringById(R.string.text_update2), stringById(R.string.text_update_bin)) { dialog ->
            dialog.setMsg(stringById(R.string.text_download_firm))
            val buf = downloadBin(id)
            ota(buf) { dialog.setMsg(it) }
        }
    }

    fun setUp(cType: Int, firm: Firm) {
        tvVersion.set(firm.version)
        tvDate.set(firm.dateFormat())
        tvDescription.set(firm.description)
        tvSize.set(firm.sizeFormat())
        btnUpdate.onClick {

            if (cType == CTYPE_APK) {
                onUpdateApk(firm.id)
            } else {
                onUpdateBin(firm.id)
            }

        }
    }
}

private class Adapter(val cType: Int, val firms: Array<Firm>) : RecyclerView.Adapter<Item>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Item {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_ota, parent, false)
        return Item(view)
    }

    override fun onBindViewHolder(holder: Item, position: Int) {
        holder.setUp(cType, firms[position])
    }

    override fun getItemCount(): Int {
        return firms.size
    }
}
